package hoja.de.trabajo;


import hoja.de.trabajo.Pila;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * ALGORITMOS Y ESTRUCTURA DE DATOS
 * SECCION 10
 * CATEDRATICO ING. ROBLES FLORES
 * HOJA DE TRABAJO 2
 * VICTOR FUENTES 12298
 * YUCELY BEB 12537
 * MARCOS LOPEZ 12519
 */

//package hoja.de.trabajo;

public class Infix {
     StringBuffer linea;//StringBuffer para expresion infix de entrada
     StringBuffer expPostfix;//StringBuffer para expresion convertida a postfix
     Lista pila;//instanciar objeto tipo pila
     Lista aux;//instanciar objeto tipo pila axuliar
     Lista resultado;//pila para los resulados
     int largo;//largo del stringbuffer de la driverhj2
     String caracter, comp;//el caracter actual y variables para comparaciones extras
     int indice;//variable para el indice de las pilas
     private int a, b;//variables a usar para usar numeros 
     private int d;//variable que almacena resultado anterior
     private String c;//variable para guardar signo actual
     //constructor
     public Infix(){
         a=0;
         b=0;
         c="";
         d=0;
         largo=0;
         indice=0;
         caracter="";
         comp="";
         pila=new Lista();
         aux=new Lista();
         resultado=new Lista();
         expPostfix=new StringBuffer();
     }
     //<>
     //metodo para agregar a la lista con nodoslista
     //operandores son: +-/*
     //operandos: son numeros enteros
     public void agregar(StringBuffer milinea){
         linea=milinea;
         for(int i=0;i<largo;i++){
             caracter=linea.substring(i, i+1);
             //System.out.println(caracter);
             switch (caracter) {
                 case "(":
                     //admitir parentesis izquierdo
                     pila.push(caracter);
                     break;
                 case ")":
                     //caracter es parentesis derecho
                     while(pila.getTamano()>0  && !pila.getUltimo().equals("(")){
                         expPostfix.append(pila.pop());
                                                                         
                     }
                     if(pila.getTamano()>0){
                        pila.pop();//eliminando el ultimo (    
                     }
                     
                     break;
                 case "0":
                     expPostfix.append(caracter);
                     break;
                 case "1":
                     expPostfix.append(caracter);
                     
                     break;
                 case "2":
                     expPostfix.append(caracter);
                     break;
                 case "3":
                     expPostfix.append(caracter);
                     break;
                 case "4":
                     expPostfix.append(caracter);
                     break;
                 case "5":
                     expPostfix.append(caracter);
                     break;
                 case "6":
                     expPostfix.append(caracter);
                     break;
                 case "7":
                     expPostfix.append(caracter);
                     break;
                 case "8":
                     expPostfix.append(caracter);
                     break;    
                 case "9":
                     expPostfix.append(caracter);
                     break;
                 
                     
                 default://if para validar otros caracteres en caso de no ser
                         // parentesis
                     
                     if(caracter.equals("+") || caracter.equals("-") || caracter.equals("*") || caracter.equals("/")){//validar operdores
                         if(pila.getTamano()==0){
                             pila.push(caracter);
                         }
                         if(pila.getTamano()!=0){
                             while(pila.getTamano()>0 && !pila.getUltimo().equals("(")){
                                 if(determinarPrioridad(pila.getUltimo(),caracter)){
                                     expPostfix.append(pila.pop());
                                 }else{
                                     break;//salida del while
                                 }
                             }
                             pila.push(caracter);//como operador con mas 
                                //prioridad que el tope de la pila, se agrega a pila
                         }
                         
                         
                         
                     }
                     
                     
                     break;
                 
             }
             
             //while(pila.getTamano()>0){
               // expPostfix.append(pila.pop());
           // }
                 
             
         }
         
     }
     
     //metodo para determinar prioridad de operadores
     //idea tomada de: http://geekswithblogs.net/venknar/archive/2010/07/09/algorithm-for-infix-to-postfix.aspx
     public boolean determinarPrioridad(String top, String in){
         if(top.equals("+")&& in.equals("*")){
            return false;//+ tiene menor prioridad que * 
         }
         if(top.equals("*")&& in.equals("-")){
             return true;//* tiene mayor prioridad que -
         }
         if(top.equals("+") && in.equals("-")){
             return true;//+ con misma prioridad que -
         }
         
         
         return true;
     }
     
     //metod para imprimir expPostfix
     public StringBuffer imprmirExpPostfix(){
         return expPostfix;
     }
     
     public int getExpPostfixTamano(){
         return expPostfix.length();
     }
     
     
     
     //metodo para reset de la lista
     public void Reset(){
         pila.limpiar();
         aux.limpiar();
         expPostfix.delete(0, largo);
         
     }
     
     //metoda push y pop para  lista pila
     public void pushPila(String str){
         pila.push(str);
     }
     
     public void popPila(){
         pila.pop();
     }
     
     //metoda push y pop para  lista auxiliar
     public void pushAux(String str){
         aux.push(str);
     }
     
     public void popAux(){
         aux.pop();
     }
     
     //metoda push y pop para  lista resultado
     public void pushResultado(String str){
         resultado.push(str);
     }
     
     public void popResultado(){
         resultado.pop();
     }
     
     public String getPilaUltimo(){
         return pila.getUltimo();
     }
     
     //metodo que mete a pila auxiliar para reordenar
     /*public void operar(){
         largo=pila.getTamano();//obtener el contador de la lista, o sea cuantos item tiene
         int i=0;
         while(i<largo){
             comp=pila.pop();
             
             
             
             i++;
         }
         
         
     }*/
     
     
     //auxiliar ya tiene los valores reordenados
     /*public void operar(){
         try{
             if(aux.getSize()%2==0){
                 System.out.println("Error en linea, numero par de caracteres");
             }else{
             
             //validación del formato inicial de un linea
             indice=aux.getSize()-1;
             a=Integer.parseInt(aux.getChar(indice));
             b=Integer.parseInt(aux.getChar(indice-1));
             indice=aux.getSize()-3;
             c=aux.getChar(indice);
             
             //d almacena resultado anterior, CUIDADO NO SOBREESCRIBIR
             if(c.equals("+")){
                 d=a+b;
             }else if(c.equals("-")){
                 d=a-b;
             }else if(c.equals("*")){
                 d=a*b;
             }else if(c.equals("/")){
                 d=a/b;
             }else{
                 System.out.println("error en operando, en:"+(indice+1)+" posicion");
             }
             
             //validación del resto de operandos y variables desde la sobreantepenultima posicion, o sea: ultima posision-4
             for(indice=aux.getSize()-4;0<indice;indice=indice-2){
               a=Integer.parseInt(aux.getChar(indice)); //a tendra variables 
               c=aux.getChar(indice-1);//c tendra los operandos
               
               if(c.equals("+")){
                 d=d+a;
             }else if(c.equals("-")){
                 d=d-a;
             }else if(c.equals("*")){
                 d=a*d;
             }else if(c.equals("/")){
                 d=d/a;
             }else{
                 System.out.println("error en operando, en:"+(indice+1)+" posicion");
             }
               
               
            }
             //guardar valores de d en la pila resultado para mostrar en pantalla
             
             resultado.push(Integer.toString(d));
         } 
             
         }catch(NumberFormatException e){
             System.out.println("error de digito");//imprimir si hay error de poner numero y signo al inicio de linea en datos.txt
         }catch(ArrayIndexOutOfBoundsException a){
             System.out.println("error en formado de linea");//si errores de formato en postfix, ej: 2 1 + 3, falta el operando de * despues de 3
         }
     
         
     }*/
     
     public void setLargo(int i){
         largo=i;
     }
     
     public String toStringPila(){
         return pila.imprimir();
     }
     
    /* public void imprimirPila(){
         pila.imprimir();
         aux.imprimir();
     }
    */
     /*public void imprimitResultado(){
         resultado.imprimir();
     }*/
    public int getA() {
        return a;
    }

    public int getB() {
        return b;
    }

    public int getD() {//variable resultado de la linea
        return d;
    }

    public String getC() {
        return c;
    }
    
    public int getCountPila(){
        return pila.getTamano();
    }
    
    //metedo para reset de todos los valores para seguir con operaciones de las lineas del archivo datos.txt
    //indice=pila.getSize()-1;0<=indice;indice=indice-1
   /* public void RESET(){
         
         
         aux.setIndice(aux.getSize()-1);
         
         
         for(indice=aux.getSize()-1;0<=indice;indice=indice-1){
           
        
            aux.pop(); 
            aux.setIndice(aux.getSize()-1);
         }
         indice=0;
         a=0;
         b=0;
         c="";
         d=0;
         largo=0;
         
         caracter="";
         
     }
    */
}
